#include "wifi_task.h"
#include "wm6201.h"
#include "string.h"
#include "elog.h"
#include "utils.h"
#include "param.h"
#include <stdarg.h>
#include <stdio.h>
#include "softtimer.h"
#include "uart.h"

u8 wifi_init_cfg(void);

typedef enum
{
	wifi_state_reset=0,
	wifi_state_init,
	wifi_state_wait_link_ap,
	wifi_state_wait_link_server,
	wifi_state_normal,
}wifi_state_t;


TaskHandle_t task_handle_wifi=NULL;
void task_wifi(void * para)
{
	u8 cmd_ret_value[48]={0};
	u32 cmd_ret_len=0;
	int ret=0;
	wifi_state_t wifi_state=wifi_state_reset;
	para=para;
	while(1)
	{
		switch((u8)wifi_state)
		{
			case wifi_state_reset:
				wm6201_hard_reset();
				vTaskDelay(pdMS_TO_TICKS(2000));
				wifi_state = wifi_state_init;
				break;
			case wifi_state_init:
				if(wifi_init_cfg()==0)
				{
					vTaskDelay(pdMS_TO_TICKS(6000));
					wifi_state = wifi_state_wait_link_ap;
				}
				else
					wifi_state = wifi_state_reset;
				break;
			case wifi_state_wait_link_ap:
			{
				static timer_t timer = 0;
				if(check_timer(timer))
				{
					timer = get_one_timer(2000);
					ret =wm6201_send_cmd((u8*)"AT+WIFI_STATE?\r\n",sizeof("AT+WIFI_STATE?\r\n"),NULL,cmd_ret_value,&cmd_ret_len,1000);
					if(ret==-2)
					{
						log_e(" check WIFI_LINK_STATE timeout ");
					}
					else if(ret ==0)
					{
						if(memcmp(cmd_ret_value,"\r\nSTA:",6)==0)
						{
							if(cmd_ret_value[6]=='1')
							{
								log_d(" wifi connected ");
								wifi_state = wifi_state_wait_link_server;
							}
							else
								log_d(" wifi connecting... ");
						}
						else
							log_w(" recv \"%s\" after check WIFI_LINK_STATE ",cmd_ret_value);
					}
				}
			}
			break;
			case wifi_state_wait_link_server:
			{
				static timer_t timer = 0;
				if(check_timer(timer))
				{
					timer = get_one_timer(2000);
					ret =wm6201_send_cmd((u8*)"AT+C0_LINK?\r\n",sizeof("AT+C0_LINK?\r\n"),NULL,cmd_ret_value,&cmd_ret_len,1000);
					if(ret==-2)
					{
						log_e(" check TCP_LINK_STATE timeout ");
					}
					else if(ret ==0)
					{
						if((memcmp(cmd_ret_value,"\r\n",2)==0)&&
							 (memcmp(&cmd_ret_value[9],"\r\nOK\r\n",6)==0))
						{
							
							log_d(" tcp state : %s ",cmd_ret_value);
							if(cmd_ret_value[2]=='1')
							{
								log_d(" tcp connected ");
								ret=wm6201_send_cmd((u8*)"AT+EXIT\r\n",sizeof("AT+EXIT\r\n"),"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,500);
								if(ret==-2)
									log_e(" exit cmd mode timeout ");
								else if(ret==-1)
									log_w(" recv \"%s\" after exit cmd mode ",cmd_ret_value);
								else
								{
									log_d(" exit cmd mode ");
									wifi_state = wifi_state_normal;
									uart_1.en_rx_timeout=false;
								}
							}
							else
								log_d(" tcp connecting... ");
						}
						else
							log_w(" recv \"%s\" after check TCP_LINK_STATE ",cmd_ret_value);
					}
				}				
			}
				break;
			case wifi_state_normal:
				break;
			default:
				break;
		}
		vTaskDelay(pdMS_TO_TICKS(1));
	}
}

u8 wifi_init_cfg(void)
{
	u8 cmd_ret_value[48]={0};
	u32 cmd_ret_len=0;
	u8 flag=0;
	int ret=0;
	if(wm6201_enter_cmd_mode()!=true)
		return 0xff;
	if((wm6201_send_cmd((u8*)"AT+ECHO=0\r\n",11,NULL,cmd_ret_value,&cmd_ret_len,1000)==0)&&(cmd_ret_len>=6))
	{
		if(memcmp("\r\nOK\r\n",&cmd_ret_value[cmd_ret_len-6],6)!=0)
		{
			log_e(" recv \"%s\" after close ECHO ",cmd_ret_value);
			return 0xff;
		}
	}
	else
	{
		log_e(" close ECHO timeout ");
		return 0xff;
	}
	
	/*CHECK WIFI MODE*/
	ret =wm6201_send_cmd((u8*)"AT+WIFI_MODE?\r\n",sizeof("AT+WIFI_MODE?\r\n"),"\r\n2\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check wifi mode timeout ");
		return 0xff;
	}
	else if(ret ==-1)
	{
		ret = wm6201_send_cmd((u8*)"AT+WIFI_MODE=2\r\n",sizeof("AT+WIFI_MODE=2\r\n"),"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
		if(ret == -2)
		{
			log_e(" set wifi mode timeout ");
			return 0xff;
		}
		else if(ret == -1)
		{
			log_e(" recv \"%s\" after set wifi mode ",cmd_ret_value);
			return 0xff;
		}
		else
			log_d(" set wifi mode to AP&STA ");
	}
	else if(ret ==0)
		log_d(" wifi mode : AP&STA ");
	
	/*CHECK C0_CONNSEND*/
	ret =wm6201_send_cmd((u8*)"AT+C0_CONNSEND?\r\n",sizeof("AT+C0_CONNSEND?\r\n"),"\r\n\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check C0_CONNSEND timeout ");
		return 0xff;
	}
	else if(ret ==-1)
	{
		ret = wm6201_send_cmd((u8*)"AT+C0_CONNSEND=\r\n",sizeof("AT+C0_CONNSEND=\r\n"),"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
		if(ret == -2)
		{
			log_e(" set C0_CONNSEND timeout ");
			return 0xff;
		}
		else if(ret == -1)
		{
			log_e(" recv \"%s\" after set C0_CONNSEND ",cmd_ret_value);
			return 0xff;
		}
		else
		{
			flag=1;
			log_d(" set C0_CONNSEND ok ");
		}
	}
	else if(ret ==0)
		log_d(" C0_CONNSEND: ");
	
	
	/*C0_CONNCTRL*/
	ret =wm6201_send_cmd((u8*)"AT+C0_CONNCTRL?\r\n",sizeof("AT+C0_CONNCTRL?\r\n"),"\r\n0\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check C0_CONNCTRL timeout ");
		return 0xff;
	}
	else if(ret ==-1)
	{
		ret = wm6201_send_cmd((u8*)"AT+C0_CONNCTRL=0\r\n",sizeof("AT+C0_CONNCTRL=0\r\n"),"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
		if(ret == -2)
		{
			log_e(" set C0_CONNCTRL timeout ");
			return 0xff;
		}
		else if(ret == -1)
		{
			log_e(" recv \"%s\" after set C0_CONNCTRL ",cmd_ret_value);
			return 0xff;
		}
		else
		{
			flag=1;
			log_d(" set C0_CONNCTRL ok ");
		}
	}
	else if(ret ==0)
		log_d(" C0_CONNCTRL: 0 ");
	

	/*C0_INACT*/
	ret =wm6201_send_cmd((u8*)"AT+C0_INACT?\r\n",sizeof("AT+C0_INACT?\r\n"),"\r\n0\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check C0_INACT timeout ");
		return 0xff;
	}
	else if(ret ==-1)
	{
		ret = wm6201_send_cmd((u8*)"AT+C0_INACT=0\r\n",sizeof("AT+C0_INACT=0\r\n"),"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
		if(ret == -2)
		{
			log_e(" set C0_INACT timeout ");
			return 0xff;
		}
		else if(ret == -1)
		{
			log_e(" recv \"%s\" after set C0_INACT ",cmd_ret_value);
			return 0xff;
		}
		else
		{
			flag=1;
			log_d(" set C0_INACT ok ");
		}
	}
	else if(ret ==0)
		log_d(" C0_INACT: 0S ");
	
	
	/*C0_ALIVE*/
	ret =wm6201_send_cmd((u8*)"AT+C0_ALIVE?\r\n",sizeof("AT+C0_ALIVE?\r\n"),"\r\n0\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check C0_ALIVE timeout ");
		return 0xff;
	}
	else if(ret ==-1)
	{
		ret = wm6201_send_cmd((u8*)"AT+C0_ALIVE=0\r\n",sizeof("AT+C0_ALIVE=0\r\n"),"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
		if(ret == -2)
		{
			log_e(" set C0_ALIVE timeout ");
			return 0xff;
		}
		else if(ret == -1)
		{
			log_e(" recv \"%s\" after set C0_ALIVE ",cmd_ret_value);
			return 0xff;
		}
		else
		{
			flag=1;
			log_d(" set C0_ALIVE ok ");
		}
	}
	else if(ret ==0)
		log_d(" C0_ALIVE: 0S ");
	
	
	/*C0_NETMODE*/
	ret =wm6201_send_cmd((u8*)"AT+C0_NETMODE?\r\n",sizeof("AT+C0_NETMODE?\r\n"),"\r\n1\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check C0_NETMODE timeout ");
		return 0xff;
	}
	else if(ret ==-1)
	{
		ret = wm6201_send_cmd((u8*)"AT+C0_NETMODE=1\r\n",sizeof("AT+C0_NETMODE=1\r\n"),"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
		if(ret == -2)
		{
			log_e(" set C0_NETMODE timeout ");
			return 0xff;
		}
		else if(ret == -1)
		{
			log_e(" recv \"%s\" after set C0_NETMODE ",cmd_ret_value);
			return 0xff;
		}
		else
		{
			flag=1;
			log_d(" set C0_NETMODE ok ");
		}
	}
	else if(ret ==0)
		log_d(" C0_NETMODE: TCP Client ");
	
	
	/*C0_BUFCLR*/
	ret =wm6201_send_cmd((u8*)"AT+C0_BUFCLR?\r\n",sizeof("AT+C0_BUFCLR?\r\n"),"\r\n1\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check C0_BUFCLR timeout ");
		return 0xff;
	}
	else if(ret ==-1)
	{
		ret = wm6201_send_cmd((u8*)"AT+C0_BUFCLR=1\r\n",sizeof("AT+C0_BUFCLR=1\r\n"),"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
		if(ret == -2)
		{
			log_e(" set C0_BUFCLR timeout ");
			return 0xff;
		}
		else if(ret == -1)
		{
			log_e(" recv \"%s\" after set C0_BUFCLR ",cmd_ret_value);
			return 0xff;
		}
		else
		{
			flag=1;
			log_d(" set C0_BUFCLR ok ");
		}
	}
	else if(ret ==0)
		log_d(" C0_BUFCLR: 1 ");
	
	
	/*STA_DHCP*/
	ret =wm6201_send_cmd((u8*)"AT+STA_DHCP?\r\n",sizeof("AT+STA_DHCP?\r\n"),"\r\n1\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check STA_DHCP timeout ");
		return 0xff;
	}
	else if(ret ==-1)
	{
		ret = wm6201_send_cmd((u8*)"AT+STA_DHCP=1\r\n",sizeof("AT+STA_DHCP=1\r\n"),"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
		if(ret == -2)
		{
			log_e(" set STA_DHCP timeout ");
			return 0xff;
		}
		else if(ret == -1)
		{
			log_e(" recv \"%s\" after set STA_DHCP ",cmd_ret_value);
			return 0xff;
		}
		else
		{
			flag=1;
			log_d(" set STA_DHCP ok ");
		}
	}
	else if(ret ==0)
		log_d(" STA_DHCP: 1 ");
	
	
	/*C0_MAXCONN*/
	ret =wm6201_send_cmd((u8*)"AT+C0_MAXCONN?\r\n",sizeof("AT+C0_MAXCONN?\r\n"),"\r\n1\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check C0_MAXCONN timeout ");
		return 0xff;
	}
	else if(ret ==-1)
	{
		ret = wm6201_send_cmd((u8*)"AT+C0_MAXCONN=1\r\n",sizeof("AT+C0_MAXCONN=1\r\n"),"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
		if(ret == -2)
		{
			log_e(" set C0_MAXCONN timeout ");
			return 0xff;
		}
		else if(ret == -1)
		{
			log_e(" recv \"%s\" after set C0_MAXCONN ",cmd_ret_value);
			return 0xff;
		}
		else
		{
			flag=1;
			log_d(" set C0_MAXCONN ok ");
		}
	}
	else if(ret ==0)
		log_d(" C0_MAXCONN: 1 ");
	
	
	/*C0_DSTPORT0*/
	ret =wm6201_send_cmd((u8*)"AT+C0_DSTPORT0?\r\n",sizeof("AT+C0_DSTPORT0?\r\n"),NULL,cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check C0_DSTPORT0 timeout ");
		return 0xff;
	}
	else if(ret ==0)
	{
		u16 port=0;
		//log_i("read C0_DSTPORT0 : %s ",cmd_ret_value);
		port = simple_strtoul((const char*)&cmd_ret_value[2],NULL,0,10);
		
		if(port!=param.server_port)
		{
			u8 send_buff[20]={0};
			u8 cmd_len=0;
			//cmd_len=vsnprintf((char*)send_buff,sizeof(send_buff),"AT+C0_PORT=%d\r\n",10);
			cmd_len=sprintf((char*)send_buff,"AT+C0_DSTPORT0=%d\r\n",param.server_port);
			ret =wm6201_send_cmd((u8*)send_buff,cmd_len,"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
			if(ret==-2)
			{
				log_e(" set C0_DSTPORT0 timeout ");
				return 0xff;
			}
			else if(ret == -1)
			{
				log_e(" recv \"%s\" after set C0_DSTPORT0 ",cmd_ret_value);
				return 0xff;
			}
			else
			{
				flag=1;
				log_d(" set C0_DSTPORT0 ok ");
			}				
		}
		else
			log_d(" C0_DSTPORT0 : %d ",param.server_port);
	}
	
	
	/*C0_DSTADDR0*/
	ret =wm6201_send_cmd((u8*)"AT+C0_DSTADDR0?\r\n",sizeof("AT+C0_DSTADDR0?\r\n"),NULL,cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check C0_DSTADDR0 timeout ");
		return 0xff;
	}
	else if(ret ==0)
	{
		if( memcmp(&cmd_ret_value[2],param.server_ip,strlen((const char*)param.server_ip))!=0)
		{
			u8 send_buff[48]={0};
			u8 cmd_len=0;
			//cmd_len=vsnprintf((char*)send_buff,sizeof(send_buff),"AT+C0_PORT=%d\r\n",10);
			cmd_len=sprintf((char*)send_buff,"AT+C0_DSTADDR0=%s\r\n",param.server_ip);
			ret =wm6201_send_cmd((u8*)send_buff,cmd_len,"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
			if(ret==-2)
			{
				log_e(" set C0_DSTADDR0 timeout ");
				return 0xff;
			}
			else if(ret == -1)
			{
				log_e(" recv \"%s\" after set C0_DSTADDR0 ",cmd_ret_value);
				return 0xff;
			}
			else
			{
				flag=1;
				log_d(" set C0_DSTADDR0 ok ");
			}				
		}
		else
			log_d(" C0_DSTADDR0 : %s ",param.server_ip);
	}
	
	/*STA_AP_SSID*/
	ret =wm6201_send_cmd((u8*)"AT+STA_AP_SSID?\r\n",sizeof("AT+STA_AP_SSID?\r\n"),NULL,cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check STA_AP_SSID timeout ");
		return 0xff;
	}
	else if(ret ==0)
	{
		if( memcmp(&cmd_ret_value[2],param.sta_ap_ssid,strlen((const char*)param.sta_ap_ssid))!=0)
		{
			u8 send_buff[48]={0};
			u8 cmd_len=0;
			//cmd_len=vsnprintf((char*)send_buff,sizeof(send_buff),"AT+C0_PORT=%d\r\n",10);
			cmd_len=sprintf((char*)send_buff,"AT+STA_AP_SSID=%s\r\n",param.sta_ap_ssid);
			ret =wm6201_send_cmd((u8*)send_buff,cmd_len,"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
			if(ret==-2)
			{
				log_e(" set STA_AP_SSID timeout ");
				return 0xff;
			}
			else if(ret == -1)
			{
				log_e(" recv \"%s\" after set STA_AP_SSID ",cmd_ret_value);
				return 0xff;
			}
			else
			{
				flag=1;
				log_d(" set STA_AP_SSID ok ");
			}				
		}
		else
			log_d(" STA_AP_SSID : %s ",param.sta_ap_ssid);
	}
	
	
	/*STA_AP_PASS*/
	ret =wm6201_send_cmd((u8*)"AT+STA_AP_PASS?\r\n",sizeof("AT+STA_AP_PASS?\r\n"),NULL,cmd_ret_value,&cmd_ret_len,1000);
	if(ret==-2)
	{
		log_e(" check STA_AP_PASS timeout ");
		return 0xff;
	}
	else if(ret ==0)
	{
		if( memcmp(&cmd_ret_value[2],param.sta_ap_pass,strlen((const char*)param.sta_ap_pass))!=0)
		{
			u8 send_buff[48]={0};
			u8 cmd_len=0;
			//cmd_len=vsnprintf((char*)send_buff,sizeof(send_buff),"AT+C0_PORT=%d\r\n",10);
			cmd_len=sprintf((char*)send_buff,"AT+STA_AP_PASS=%s\r\n",param.sta_ap_pass);
			ret =wm6201_send_cmd((u8*)send_buff,cmd_len,"\r\nOK\r\n",cmd_ret_value,&cmd_ret_len,1000);
			if(ret==-2)
			{
				log_e(" set STA_AP_PASS timeout ");
				return 0xff;
			}
			else if(ret == -1)
			{
				log_e(" recv \"%s\" after set STA_AP_PASS ",cmd_ret_value);
				return 0xff;
			}
			else
			{
				flag=1;
				log_d(" set STA_AP_PASS ok ");
			}				
		}
		else
			log_d(" STA_AP_PASS : %s ",param.sta_ap_pass);
	}
	
	
	if(flag)
		return 1;
	else
		return 0;
}




